﻿// -------------------------------------------------------------------------
//    @FileName         :    NFPkgMng.cpp
//    @Author           :    gaoyi
//    @Date             :    24-7-30
//    @Email            :    445267987@qq.com
//    @Module           :    NFPkgMng
//
// -------------------------------------------------------------------------

#include "NFPkgMng.h"
#include "DescStore/MsgMonitorMsgMonitorDesc.h"
#include "NFOperatingStatistcsMgr.h"

NFPkgMng::NFPkgMng()
{
	if (EN_OBJ_MODE_INIT == NFShmMgr::Instance()->GetCreateMode())
	{
		CreateInit();
	}
	else
	{
		ResumeInit();
	}
}

NFPkgMng::~NFPkgMng()
{
}

int NFPkgMng::CreateInit()
{
	m_astInputInfo.resize(m_astInputInfo.max_size());
	m_msgStatisticInfo.resize(m_msgStatisticInfo.max_size());
	return 0;
}

int NFPkgMng::ResumeInit()
{
	return 0;
}

int NFPkgMng::CheckPkgRate(int iMsgID, int& count, int& interval)
{
	CHECK_EXPR((iMsgID > 0 && iMsgID < proto_ff::E_CS_MAX_CMD_ID_VALUE), CMDID_OUT_MAX_VALUE, "invalid msg::{}", iMsgID);

	interval = 0;
	count = 0;
	int64_t ullTimeMs = NFGetTime();

	int iMsgControlInterval = DEFAULT_MSG_CONTROL_INTERVAL;
	int iMsgMinInterval = DEFAULT_MSG_MIN_INTERVAL;
	int iMaxIntervalCount = DEFAULT_MSG_INTERVAL_LIMIT_COUNT;
	auto pMonitorDesc = MsgMonitorMsgMonitorDesc::Instance()->GetDesc(iMsgID);
	if (pMonitorDesc)
	{
		iMsgControlInterval = pMonitorDesc->control_time;
		iMsgMinInterval = pMonitorDesc->min_interval;
		iMaxIntervalCount = pMonitorDesc->upper_limit;
	}

	if (m_astInputInfo[iMsgID].m_iBeginTime == 0)
	{
		m_astInputInfo[iMsgID].m_iBeginTime = ullTimeMs;
		m_astInputInfo[iMsgID].m_iLastTime = ullTimeMs;
		m_astInputInfo[iMsgID].m_iCount = 1;
	}
	else
	{
		if (ullTimeMs - m_astInputInfo[iMsgID].m_iLastTime < iMsgMinInterval)
		{
			interval = ullTimeMs - m_astInputInfo[iMsgID].m_iLastTime;
			return PKG_RATE_UPPER_LIMIT;
		}

		if (ullTimeMs - m_astInputInfo[iMsgID].m_iBeginTime > iMsgControlInterval)
		{
			m_astInputInfo[iMsgID].m_iBeginTime = ullTimeMs;
			m_astInputInfo[iMsgID].m_iCount = 0;
		}

		m_astInputInfo[iMsgID].m_iLastTime = ullTimeMs;
		++m_astInputInfo[iMsgID].m_iCount;
		if (m_astInputInfo[iMsgID].m_iCount > iMaxIntervalCount)
		{
			interval = ullTimeMs - m_astInputInfo[iMsgID].m_iBeginTime;
			count = m_astInputInfo[iMsgID].m_iCount;
			return MSG_PKG_RATE_UPPER_LIMIT;
		}
	}

	return 0;
}

int NFPkgMng::AddPkgStatistic(int iMsgID, uint64_t roleID, uint64_t uin)
{
	CHECK_EXPR((iMsgID > 0 && iMsgID < proto_ff::E_CS_MAX_CMD_ID_VALUE), CMDID_OUT_MAX_VALUE, "invalid msg::{}", iMsgID);

	int64_t ullTimeMs = NFGetTime();;
	if (m_msgStatisticInfo[iMsgID].m_lastMinBeginTime == 0)
	{
		m_msgStatisticInfo[iMsgID].m_lastMinBeginTime = ullTimeMs;
		m_msgStatisticInfo[iMsgID].m_lastMaxBeginTime = ullTimeMs;
		m_msgStatisticInfo[iMsgID].m_lastMinCount = 1;
		m_msgStatisticInfo[iMsgID].m_lastMaxCount = 1;
	}
	else
	{
		bool isLog = false;

		if (ullTimeMs - m_msgStatisticInfo[iMsgID].m_lastMinBeginTime > DEFAULT_MSG_STATISTIC_MIN_INTEVAL)
		{
			m_msgStatisticInfo[iMsgID].m_lastMinCount = 1;
			m_msgStatisticInfo[iMsgID].m_lastMinBeginTime = ullTimeMs;
		}
		else
		{
			m_msgStatisticInfo[iMsgID].m_lastMinCount += 1;
		}

		if (m_msgStatisticInfo[iMsgID].m_lastMinCount > m_msgStatisticInfo[iMsgID].m_minCount)
		{
			NFLogTrace(NF_LOG_DEFAULT, 0, "msg statistic, msgId:{}, minCount:{}, lastMinCount:{}", iMsgID, m_msgStatisticInfo[iMsgID].m_minCount, m_msgStatisticInfo[iMsgID].m_lastMinCount);
			m_msgStatisticInfo[iMsgID].m_minCount = m_msgStatisticInfo[iMsgID].m_lastMinCount;
			isLog = true;
		}

		if (ullTimeMs - m_msgStatisticInfo[iMsgID].m_lastMaxBeginTime > DEFAULT_MSG_STATISTIC_MAX_INTEVAL)
		{
			m_msgStatisticInfo[iMsgID].m_lastMaxCount = 1;
			m_msgStatisticInfo[iMsgID].m_lastMaxBeginTime = ullTimeMs;
		}
		else
		{
			m_msgStatisticInfo[iMsgID].m_lastMaxCount += 1;
		}

		if (m_msgStatisticInfo[iMsgID].m_lastMaxCount > m_msgStatisticInfo[iMsgID].m_maxCount)
		{
			m_msgStatisticInfo[iMsgID].m_maxCount = m_msgStatisticInfo[iMsgID].m_lastMaxCount;
			isLog = true;
		}

		if (isLog)
		{
			NFOperatingStatistcsMgr::Instance()->AddSessionMsgStatistic(iMsgID, m_msgStatisticInfo[iMsgID].m_minCount,
													 m_msgStatisticInfo[iMsgID].m_maxCount, roleID, uin);
		}
	}

	return 0;
}
